package sivan.mybatis;

import org.apache.ibatis.type.JdbcType;
import org.junit.Test;
import sivan.domain.Blog;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JDBCDemo {

    /**
     * JDBC简单实现
     */
    @Test
    public void test1() {
        try {
            //加载数据库驱动
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://112.74.161.161:3306/mybatis",
                    "root", "28b21c1cfd");
            Integer id = 1;
            String sql = "SELECT * FROM blog WHERE id = #{id}";

            sql = this.parse(sql);
            PreparedStatement pstmt = conn.prepareStatement(sql);
//            pstmt.setInt(1, 1);
            pstmt.execute();
            ResultSet resultSet = pstmt.getResultSet();
            JdbcResultSetWrapper wrapper = new JdbcResultSetWrapper(pstmt);
            Blog blog = new Blog();
//            while (resultSet.next()) {
//                List<String> columnNames = wrapper.getColumnNames();
//                for (String columnName : columnNames) {
//                    Object value = resultSet.getObject(columnName);
//                    Field field = Blog.class.getDeclaredField(columnName);
//                    field.setAccessible(true);
//                    field.set(blog, value);
//                }
//            }

            MyTypeHandlerFactory factory = new MyTypeHandlerFactory();
            List<String> columnNames = wrapper.getColumnNames();
            List<String> columnClassNames = wrapper.getColumnClassNames();
            List<JdbcType> jdbcTypes = wrapper.getJdbcTypes();
            while (resultSet.next()) {
                for (int i = 0; i < columnClassNames.size(); i++) {
                    Object value = factory.getHandler(jdbcTypes.get(i)).getResult(resultSet, columnNames.get(i));
                    Method method = Blog.class.getMethod("set" + captureName(columnNames.get(i)),
                            Class.forName(columnClassNames.get(i)));
                    method.invoke(blog, value);
                }
            }
            System.out.println(blog);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String parse(String sql) {
        return null;
    }

    public String captureName(String columnName) {
        char[] cs = columnName.toCharArray();
        cs[0] -= 32;
        return String.valueOf(cs);
    }


    static class JdbcResultSetWrapper {
        private final List<String> columnNames = new ArrayList<>();
        private final List<String> columnClassNames = new ArrayList<>();
        private final List<JdbcType> jdbcTypes = new ArrayList<>();

        JdbcResultSetWrapper(PreparedStatement pstmt) throws SQLException {
            ResultSet resultSet = pstmt.getResultSet();
            ResultSetMetaData mateData = resultSet.getMetaData();
            int columnCount = mateData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                columnNames.add(mateData.getColumnName(i));
                columnClassNames.add(mateData.getColumnClassName(i));
                jdbcTypes.add(JdbcType.forCode(mateData.getColumnType(i)));
            }
        }

        public List<String> getColumnNames() {
            return columnNames;
        }

        public List<String> getColumnClassNames() {
            return columnClassNames;
        }

        public List<JdbcType> getJdbcTypes() {
            return jdbcTypes;
        }
    }
}
